/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fsktms.request.api;

import fsktms.IMessage;
import fsktms.messagemanager.IMessageListener;
import fsktms.request.RequestParameters;
import fsktms.server.NetServer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author salm
 */
public class RequestAPIManager implements IMessageListener
{
    private Map<String, RequestAPI> APIs = new HashMap<>();
    private NetServer netSv;
    
    public RequestAPIManager(NetServer netServer)
    {
        this.netSv = netServer;
    }
    
    @Override
    public void onHasNewMessage(final IMessage msg)
    {
        ObjectInputStream objIS;
        try {
            objIS = new ObjectInputStream(new ByteArrayInputStream(msg.getData()));
            final Long reqID = objIS.readLong();
            final String reqName = (String) objIS.readObject();
            final RequestParameters reqParams = (RequestParameters) objIS.readObject();
            if (reqName != null && reqParams != null)
            {
                if (this.APIs.containsKey(reqName))
                {
                    final RequestAPI api = this.APIs.get(reqName);
                    
                    (new Thread()
                    {
                        @Override
                        public void run()
                        {
                            ObjectOutputStream objOS = null;
                            try {
                                RequestParameters respond = api.execute(reqParams);
                                ByteArrayOutputStream bOS = new ByteArrayOutputStream();
                                objOS = new ObjectOutputStream(bOS);
                                objOS.writeLong(reqID);
                                objOS.writeObject(respond);
                                netSv.sendMessage(msg.getHostAddress(), bOS.toByteArray(), msg.getMagicKey());
                            } catch (IOException ex) {
                                Logger.getLogger(RequestAPIManager.class.getName()).log(Level.SEVERE, null, ex);
                            } finally {
                                try {
                                    objOS.close();
                                } catch (IOException ex) {
                                    Logger.getLogger(RequestAPIManager.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                        }
                    }).start();
                }
            }
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger(RequestAPIManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void addAPI(RequestAPI api)
    {
        this.APIs.put(api.apiName(), api);
    }
    
    public void removeAPI(String apiName)
    {
        this.APIs.remove(apiName);
    }
    
    public RequestAPI getAPI(String apiName)
    {
        return this.APIs.get(apiName);
    }
}
